// BaseShader.java
package com.goldsprite.gameframeworks.shaders;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.goldsprite.gameframeworks.ecs.system.GameSystem;
import com.goldsprite.gameframeworks.log.*;

public abstract class BaseShader {
    public final ShaderProgram shaderProgram;

	protected float time;

    public BaseShader(String vertexShaderPath, String fragmentShaderPath) {
        String vertexShader = loadShaderFile(vertexShaderPath);
        String fragmentShader = loadShaderFile(fragmentShaderPath);

        shaderProgram = new ShaderProgram(vertexShader, fragmentShader);

        if (!shaderProgram.isCompiled()) {
            Debug.logT("Shader", "%s 编译失败: %s", getClass().getSimpleName(), shaderProgram.getLog());
        } else {
            Debug.logT("Shader", "%s 着色器编译成功", getClass().getSimpleName());
            initUniforms();
        }
    }

	public float getUTime() {
		return time = GameSystem.getTotalDeltaTime();
	}

    /**
     * 子类需要实现此方法来初始化特定的uniform
     */
    protected abstract void initUniforms();

    /**
     * 子类需要实现此方法来设置特定的uniform
     */
    public abstract void setUniforms();

    public void update(float delta) {
    }

    public void begin(Batch batch) {
        batch.setShader(shaderProgram);
        setUniforms();
    }

    public void end(Batch batch) {
        batch.setShader(null);
    }

    public void dispose() {
        shaderProgram.dispose();
    }

    public ShaderProgram getShaderProgram() {
        return shaderProgram;
    }

    protected String loadShaderFile(String path) {
        try {
            return Gdx.files.internal(path).readString();
        } catch (Exception e) {
            Gdx.app.error("BaseShader", "无法加载着色器文件: " + path, e);
            return "";
        }
    }

    // 通用的uniform设置方法
    protected int getUniformLocation(String name) {
        return shaderProgram.getUniformLocation(name);
    }

    protected void setUniformf(int location, float value) {
        if (location >= 0) shaderProgram.setUniformf(location, value);
    }

    protected void setUniformf(int location, float v1, float v2) {
        if (location >= 0) shaderProgram.setUniformf(location, v1, v2);
    }

    protected void setUniformf(int location, float v1, float v2, float v3) {
        if (location >= 0) shaderProgram.setUniformf(location, v1, v2, v3);
    }

    protected void setUniformf(int location, float v1, float v2, float v3, float v4) {
        if (location >= 0) shaderProgram.setUniformf(location, v1, v2, v3, v4);
    }

    protected void setUniform1fv(int location, float[] values, int count) {
        if (location >= 0) shaderProgram.setUniform1fv(location, values, 0, count);
    }
}
